//选择条款条目
<template>
  <el-dialog
    title="选择条款条目"
    :visible.sync="visibleStatus"
    width="50%"
    @close="onClose"
    @open="dialogOpen"
    append-to-body
  >
    <div>
      <el-select
        v-model="bacisContractId"
        style="border: 1px solid"
        @change="changeSelect"
      >
        <el-option
          v-for="item in bacisContractList"
          :key="item.id"
          :value="item.id"
          :label="item.clauseName"
        ></el-option>
      </el-select>
    </div>
    <el-table
      :data="tableDatas"
      border
      style="width: 100%; margin-top: 5px"
      class="table"
      row-key="id"
      :tree-props="{
        children: 'children',
        hasChildren: 'hasChildren',
      }"
      ref="multipleTablePop"
      @select="selectBtn"
      @select-all="allSelect"
    >
      <el-table-column type="selection"></el-table-column>
      <el-table-column label="条目编号" header-align="center" width="120px">
        <template slot-scope="scope">
          {{ scope.row.num }}
        </template>
      </el-table-column>
      <el-table-column
        prop="name"
        label="名称"
        min-width="30%"
        header-align="center"
      >
      </el-table-column>
      <el-table-column
        prop="content"
        label="条款条目内容"
        min-width="50%"
        header-align="center"
      >
      </el-table-column>
    </el-table>
    <span slot="footer" class="dialog-footer">
      <el-button @click="onCancel">取 消</el-button>
      <el-button type="primary" @click="onConfirm">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
export default {
    data () {
        return {
            bacisContractList: [],
            visibleStatus: false,
            returnTableData: [],
            tableDatas: [],
            bacisContractId: '',
            oldSelection: [], // 保存上次一选择的角色用例，用于匹配查出当前选中或取消的行
            selType: '', // 判断分配菜单用例触发事件是点击用例复选框还是列头的复选框，避免事件重复触发
            saveSelected: [], //保存当前的已经勾选选中的数据
            contractAppraiseClauseData: {
                billId: null,
                templateId: null, //合同id
                contractAppraiseClause: [],
            },
        }
    },

    props: {
        contractDialog: {
            type: Boolean,
            default: false,
        },
        billId: {
            type: String,
            default: '',
        },
    },
    watch: {
        contractDialog () {
            this.visibleStatus = this.contractDialog
        },
    },

    created () {
        this.getBacisContract()
    },
    methods: {
        async getBacisContract () {
            this.bacisContractList = await this.$Ajax.httpPost(
                '/bacisContract/listEntity',
                {}
            )
        },
        //获取合同条款
        async getBacisList () {
            let data = await this.$Ajax.httpGet(
                `/bacisContract/listByContractId/${this.bacisContractId}`
            )
            this.returnTableData = data
            let treeData = this.toTree(data)
            this.tableDatas = treeData
        },
        changeSelect () {
            this.getBacisList()
        },
        toTree (data) {
            let result = []
            if (!Array.isArray(data)) {
                return result
            }
            data.forEach(item => {
                delete item.children
            })
            let map = {}
            data.forEach(item => {
                map[item.id] = item
            })
            data.forEach(item => {
                let parent = map[item.parentId]
                if (parent) {
                    (parent.children || (parent.children = [])).push(item)
                } else {
                    result.push(item)
                }
            })
            return result
        },
        selectBtn (selection, row) {
            console.log('selectBtn: ', selection, this.selType)
            if (this.selType !== '') {
                return
            } else {
                this.selType = 'select'
                window.setTimeout(() => {
                    this.selType = ''
                }, 100)
            }
            //判断是选中还是取消
            let selFlag = false
            // 在选中列表中查找当前行，如果找到就是选中
            const finded = selection.find(item => item.id === row.id)
            if (finded) {
                selFlag = true
                this.recurSelectParent(row, true) // 递归找父级，选中父级
                this.childAllSelCalleArr(row, selFlag) //子级全部选中的递归
            } else {
                // 递归找父级，取消父级
                this.recurUnSelectParent(row, false, selection)
                //子级全部取消选中
                this.childAllDelCalleArr(selection, row, selFlag) //子级全部 取消 的递归函数
            }
            // 设置当前行
            this.$refs.multipleTablePop.toggleRowSelection(row, selFlag)
            if (selFlag) {
                this.saveSelected.push(row)
            } else {
                this.cancelSaveSelected(row)
            }
            this.oldSelection = JSON.parse(JSON.stringify(selection))
        },
        // 递归找父级，选中父级
        recurSelectParent (row, flag) {
            if (row.parentId === '0') return
            let findObj = this.returnTableData.find(
                item => item.id === row.parentId
            )
            if (findObj) {
                console.log(JSON.parse(JSON.stringify(findObj)), '选中父级')
                this.$refs.multipleTablePop.toggleRowSelection(findObj, flag)
                this.saveSelected.push(findObj) //当前选中的父级存进数组
                // 继续往上递归处理父级
                this.recurSelectParent(findObj, flag)
            }
        },
        // 递归找父级，取消父级
        recurUnSelectParent (row, flag, selection) {
            //用当前行的parentId找父级
            let findObj = this.returnTableData.find(
                item => item.id === row.parentId
            )
            if (findObj) {
                console.log('找到父级')
                // 判断兄弟节点是否全部取消
                // 先找出兄弟节点
                // 然后再看选中列表中是否包含兄弟节点&&排除自己
                const siblingNode = this.returnTableData.filter(
                    item => item.parentId === row.parentId && item.id !== row.id
                )
                console.log(siblingNode, '取消的兄弟节点')
                // 有兄弟节点，则需判断是否有选中
                if (siblingNode.length > 0) {
                    // 判断父级是否有兄弟节点被选中
                    let hasSel = selection.find(item => {
                        return siblingNode.find(
                            siblingItem => siblingItem.id === item.id
                        )
                    })
                    // console.log("兄弟节点是否选中: ", hasSel);
                    // 如果没有其他兄弟节点被选中，则取消父级
                    if (!hasSel) {
                        this.$refs.multipleTablePop.toggleRowSelection(findObj, flag)
                        this.cancelSaveSelected(findObj)
                        // 继续往上递归处理父级
                        this.recurUnSelectParent(findObj, flag, selection)
                    }
                } else {
                    this.$refs.multipleTablePop.toggleRowSelection(findObj, flag)
                    this.cancelSaveSelected(findObj)

                    if (row.parentId === '0') return
                    // 继续往上递归处理父级
                    this.recurUnSelectParent(findObj, flag, selection)
                }
            }
        },
        //全选时，对每一行都执行选中事件
        allSelect (selection) {
            // 如果是其它事件触发，则不再重复触发
            if (this.selType !== '') return
            //判断当前勾选事件使用的点击用例复选框还是列头的复选框
            this.selType = 'allSelect'
            setTimeout(() => {
                this.selType = ''
            }, 100)
            //如果选中 自己也选中
            //判断是选中还是取消 只有从是否增加选项中来判断
            // 这里需要用到递归
            const sel = selection.length > this.oldSelection.length
            console.log('sel: ', sel)
            this.saveSelected = []
            this.allSelCalleArr(this.tableDatas, sel) //递归函数
            this.oldSelection = JSON.parse(JSON.stringify(selection))
        },
        //全选时候的递归函数
        allSelCalleArr (arr, sel) {
            arr.forEach(item => {
                this.$refs.multipleTablePop.toggleRowSelection(item, sel)
                if (sel) {
                    this.saveSelected.push(item)
                } else {
                    this.cancelSaveSelected(item)
                }
                if (item.children) {
                    this.allSelCalleArr(item.children, sel)
                }
            })
        },
        //子级全部 选中 的递归函数
        childAllSelCalleArr (row, selFlag) {
            if (row.children) {
                row.children.forEach(item => {
                    this.$refs.multipleTablePop.toggleRowSelection(item, selFlag)
                    this.saveSelected.push(item)
                    if (item.children) {
                        this.childAllSelCalleArr(item, selFlag)
                    }
                })
            }
        },
        //子级全部 取消 的递归函数
        childAllDelCalleArr (selection, row, selFlag) {
            if (row.children) {
                row.children.forEach(item => {
                    this.$refs.multipleTablePop.toggleRowSelection(item, selFlag)
                    this.cancelSaveSelected(item)
                    // 选中列表中去掉已取消选中的子级项
                    const selIndex = selection.findIndex(
                        selItem => selItem.id === item
                    )
                    selection.splice(selIndex, 1)
                    if (item.children) {
                        this.childAllDelCalleArr(selection, item, selFlag)
                    }
                })
            }
        },
        // 取消选中项
        cancelSaveSelected (row) {
            let findIndex = this.saveSelected.findIndex(item => item.id === row.id)
            // console.log("findIndex: ", findIndex);
            this.saveSelected.splice(findIndex, 1)
        },

        dialogOpen () {
            this.getBacisContract()
        },
        onConfirm () {
            console.log(this.billId, '获取当前id')
            this.contractAppraiseClauseData.billId = this.billId

            if ([...this.saveSelected].length > 0) {
                this.contractAppraiseClauseData.templateId = [
                    ...this.saveSelected,
                ][0].contractId
                for (let obj of [...this.saveSelected]) {
                    if (obj.children) {
                        delete obj.children
                    }
                    obj.sourceId = obj.id
                    delete obj.id
                }
                // console.log(this.contractAppraiseClauseData, "打印");
                console.log([...this.saveSelected], '打印我')
                this.contractAppraiseClauseData.contractAppraiseClause = [
                    ...this.saveSelected,
                ]
                this.$emit('contractData', this.contractAppraiseClauseData)
                this.onCancel()
            }

            // 包勾选后的数据保存
        },
        onCancel () {
            this.onClose()
        },
        onClose () {
            this.tableDatas = []
            this.saveSelected = []
            this.bacisContractId = ''
            this.$emit('closePop')
        },
    },
}
</script>

<style lang="scss" scoped>
::v-deep.el-input__inner {
  border: 1px;
}
</style>